package com.kxf.zxingmini.view;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.google.zxing.Result;
import com.kxf.zxingmini.interfaces.IScan;
import com.kxf.zxingmini.interfaces.ScanViewCallBack;
import com.kxf.zxingmini.zxing.DecodeHelper;

import java.io.ByteArrayOutputStream;

/**
 * @ProjectName: AndroidTestDemo
 * @Package: com.kxf.zxingmini.view
 * @ClassName: ScanView
 * @Description: java类作用描述
 * @Author: kuangxuefeng
 * @qq: 1024883177
 * @CreateDate: 2021/3/24 11:21
 */
public class ScanView extends SurfaceView implements IScan {
    private Camera mCamera;
    private DecodeHelper decodeHelper;
    private Handler decodeHandler;
    private Handler uiHandler;

    private ScanViewCallBack scanViewCallBack;

    private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(final byte[] data, Camera camera) {
            final Camera.Size size = camera.getParameters().getPreviewSize();
            try(ByteArrayOutputStream stream = new ByteArrayOutputStream()){
                YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
                if(image!=null){
                    image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream);

                    Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
                    //**********************
                    //因为图片会放生旋转，因此要对图片进行旋转到和手机在一个方向上
                    final Bitmap bmpNew = rotateMyBitmap(bmp);
                    //**********************************
                    System.out.println("scanViewCallBack===>>>" + scanViewCallBack);
                    if (scanViewCallBack!=null){
                        scanViewCallBack.scaning(bmpNew);
                    }
                    decodeHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            final Result result = decodeHelper.decode(data, size.width, size.height);
                            if (result!=null && !TextUtils.isEmpty(result.getText())){
                                System.out.println("扫码成功===>>>" + result.getText());
                                uiHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (scanViewCallBack!=null){
                                            scanViewCallBack.scanSuccess(bmpNew, result);
                                        }
                                    }
                                });
                            }else {
                                System.out.println("扫码失败===>>>" + result);
                                mCamera.setOneShotPreviewCallback(previewCallback);
                                mCamera.autoFocus(autoFocusCallback);
                            }
                        }
                    });
                }
            }catch(Exception e){
                Log.e("ScanView", "onPreviewFrame", e);
            }

        }
    };

    public ScanView(Context context) {
        super(context);
        init();
    }

    public ScanView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ScanView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ScanView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public void init(){
        HandlerThread handlerThread = new HandlerThread("decodeHandlerThread");
        handlerThread.start();
        decodeHandler = new Handler(handlerThread.getLooper());
        decodeHelper = new DecodeHelper();
        uiHandler = new Handler(Looper.getMainLooper());

        this.getHolder().addCallback(new SurfaceHolder.Callback2() {
            @Override
            public void surfaceRedrawNeeded(@NonNull SurfaceHolder holder) {

            }

            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                prepareScan();
                startScan();
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                if (mCamera!=null){
                    mCamera.release();
                }
            }
        });

    }


    private void prepareScan() {
        mCamera = Camera.open();
        Camera.Parameters parameters = mCamera.getParameters();
//        camera.setParameters(parameters);
        if (getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
            // 如果是竖屏
            // parameters.set("orientation", "portrait");
            // 在2.2以上可以使用
            mCamera.setDisplayOrientation(90);
        } else {
            // parameters.set("orientation", "landscape");
            // 在2.2以上可以使用
            mCamera.setDisplayOrientation(0);
        }
        try {
            mCamera.setPreviewDisplay(this.getHolder());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void startScan() {
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                mCamera.setOneShotPreviewCallback(previewCallback);
                mCamera.startPreview();
                mCamera.autoFocus(autoFocusCallback);
            }
        });
    }

    @Override
    public void reStartScan() {
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                mCamera.setOneShotPreviewCallback(previewCallback);
                mCamera.startPreview();
                mCamera.autoFocus(autoFocusCallback);
            }
        });
    }

    @Override
    public void stopScan() {
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                mCamera.stopPreview();
            }
        });
    }

    //旋转图片
    public Bitmap rotateMyBitmap(Bitmap bmp){
        //*****旋转一下
        Matrix matrix = new Matrix();
        matrix.postRotate(90);

        Bitmap nbmp2 = Bitmap.createBitmap(bmp, 0,0, bmp.getWidth(),  bmp.getHeight(), matrix, true);
        return nbmp2;
    }

    public void setScanViewCallBack(ScanViewCallBack scanViewCallBack) {
        this.scanViewCallBack = scanViewCallBack;
    }
}
